package com.spudtech
{
    
    import flash.geom.*;
    import flash.events.*;
    import flash.display.*;
    
    import flash.utils.Dictionary;
    
    import com.spudtech.utils.*;
    
    
    public class SpudRoot
    {
        // Static class with utility bits
        
        protected static var _globals : Dictionary;
        
        protected static var _screen : SpudScreen;
        
        protected static var _paused : Boolean;
        
        public static function init() : void
        {
            // Initialize things
            
            _paused = false;
            
            _screen = new SpudScreen(
                    gameWidth,
                    gameHeight
            );
            
            screenColor = 0x000000;
            
            // Create the global value dictionary
            _globals = new Dictionary();
            
        }
        
        public static function get paused() : Boolean
        {
            return _paused;
        }
        public static function set paused(is_paused : Boolean) : void
        {
            _paused = is_paused;
        }
        
        public static function get resourceMgr() : SpudResourceManager
        {
            return SpudResourceManager.resourceMgr;
        }
        
        public static function get screen() : SpudScreen
        {
            return _screen;
        }
        
        public static function get mainApp() : SpudGame
        {
            return SpudGame.mainApp;
        }
        
        public function get scene() : SpudScene
        {
            return mainApp.scene;
        }
        public function set scene(new_scene : SpudScene) : void
        {
            mainApp.scene = new_scene;
        }
        
        public static function get inputMgr() : SpudInput
        {
            return SpudInput.inputMgr;
        }
        public static function get keys() : SpudKey
        {
            return inputMgr.keys;
        }
        
        public static function get gameWidth() : uint
        {
            return SpudGame.mainApp.scrollRect.width;
        }
        public static function get gameHeight() : uint
        {
            return SpudGame.mainApp.scrollRect.height;
        }
        
        public static function get screenColor() : uint
        {
            return screen.backColor;
        }
        public static function set screenColor(new_color : uint) : void
        {
            screen.backColor = new_color;
        }
        
        public static function get globals() : Dictionary
        {
            return _globals;
        }
        
        
        public static function getGlobal(name : *) : Object
        {
            // Get a global value
            
            var val_name : String = String(name).toLowerCase();
            
            return globals[val_name];
            
        }
        public static function setGlobal(name : *, value : *) : void
        {
            // Set a global value
            
            var val_name : String = String(name).toLowerCase();
            
            globals[val_name] = value;
            
        }
        
        
        public static function lerpAmount(start : Number, end : Number, amount : Number) : Number
        {
            // amount is a number between 0.0 and 1.0
            // It is the percentage of the lerp between
            // start and end
            // An amount of 0.0 is at the start
            // An amount of 1.0 is at the end
            // An amount of 0.5 is at the midpoint
            
            var dist : Number = end - start;
            dist *= amount;
            
            return start + dist;
            
        }
        
        public static function lerp(start : Number, end : Number,
                                    steps : uint, num_steps : uint) : Number
        {
            return lerpAmount(start, end, (steps / num_steps));
        }
        
        public static function lerpAngleAmount(start : Number, end : Number, amount : Number) : Number
        {
            var dist : Number = end - start;
            
            if (dist > 180)
            {
                dist -= 360;
            }
            else if (dist < -180)
            {
                dist += 360;
            }
            
            dist *= amount;
            
            return start + dist;
            
        }
        
        public static function lerpAngle(start : Number, end : Number,
                                         steps : uint, num_steps : uint) : Number
        {
            return lerpAngleAmount(start, end, (steps / num_steps));
        }
        
        public static function lerpPointAmount(start : Point, end : Point, amount : Number) : Point
        {
            var current : Point = start.clone();
            
            var dist_x : Number = end.x - start.x;
            var dist_y : Number = end.y - start.y;
            
            dist_x *= amount;
            dist_y *= amount;
            
            current.x += dist_x;
            current.y += dist_y;
            
            return current;
            
        }
        
        public static function lerpPoint(start : Point, end : Point, steps : uint, num_steps : uint) : Point
        {
            return lerpPointAmount(start, end, (steps / num_steps));
        }
        
        public static function colorLerpAmount(start : uint, end : uint, amount : Number) : uint
        {
            // TODO
            return 0x000000;
        }
        
        public static function colorLerp(start : uint, end : uint, steps : uint, num_steps : uint) : uint
        {
            return colorLerpAmount(start, end, (steps / num_steps));
        }
        
        
        public static function getDiagonal(width : Number, height : Number) : Number
        {
            if (width <= 0 || height <= 0)
            {
                return 0.0;
            }
            
            // C squared equal (A squared plus B squared)
            // C equals the square root of (A squared plus B squared)
            
            return Math.sqrt(Math.pow(width,2) + Math.pow(height,2));
            
        }
        
        public static function getSizeDiagonal(size : Point) : Number
        {
            return getDiagonal(size.x, size.y);
        }
        
        public static function getRectDiagonal(area : Rectangle) : Number
        {
            return getDiagonal(area.width, area.height);
        }
        
        public static function getBitmapDiagonal(bitmap : *) : Number
        {
            if (!(bitmap is Bitmap || bitmap is BitmapData))
            {
                throw new TypeError("Given bitmap must be either a Bitmap or a BitmapData");
            }
            
            return getDiagonal(bitmap.width, bitmap.height);
            
        }
        
        public static function getBitmapClipRect(bitmap : *) : Rectangle
        {
            // Get a clip rectangle that
            // is guaranteed to cover
            // an ENTIRE bitmap
            
            if (!(bitmap is Bitmap || bitmap is BitmapData))
            {
                throw new TypeError("Given bitmap must be either a Bitmap or a BitmapData");
            }
            
            var clip_rect : Rectangle = new Rectangle(0,0,getBitmapDiagonal(bitmap),getBitmapDiagonal(bitmap));
            
            // We center the clip rectangle
            
            // Clip rect top-left on bitmap center
            clip_rect.x = bitmap.width / 2.0;
            clip_rect.y = bitmap.height / 2.0;
            
            // Clip rect center on bitmap center
            clip_rect.x -= clip_rect.width / 2.0;
            clip_rect.y -= clip_rect.height / 2.0;
            
            return clip_rect;
            
            
        }
        
        
    }
    
}
